<?php
namespace Project_725\Model;

use Zend\Db\Sql\Predicate\PredicateSet;
use Zend\Db\Sql\Select; 
use TwinPeaks\Core as Core;

class User extends Base
{
	const SEX_MALE = 'male';
	const SEX_FEMALE = 'female';

	const USER_SALT = '94hmcns287sjhxa;kn';
	const ACCESS_TOKEN_LENGTH = 24;
	const DEFAULT_PASS_LENGTH = 6;
	
	/**
	 * @var \Zend\Db\TableGateway\TableGateway
	 */
	static protected $_tableGW;
	
	/**
	 * @var \DateTime 
	 */
	protected $locUpdateTime;

	/**
	 * @return void
	 */
	protected function init($tableName = null)
	{
		parent::init('user');
	}
	
	/**
	 * @return User|null
	 */
	static function getByAccessToken($token)
	{
		return self::getByColumn('access_token', $token);
	}
	
	/**
	 * @return User|null
	 */
	static function getById($id)
	{
		return self::getByColumn('id', $id);
	}
	
	/**
	 * @return User|null
	 */
	static function getByEmail($email)
	{
		return self::getByColumn('email', $email);
	}
	
	/**
	 * @return User|null
	 */
	static function getByConfirmCode($code)
	{
		return self::getByColumn('confirm_code', $code);
	}
	
	/**
	 * @return string
	 */
	static protected function getEncryptedPass($pass)
	{
		return sha1($pass . self::USER_SALT);
	}

	/**
	 * @return integer
	 */
	static function signUp($email, $pass, $sex, $confirmCode = '')
	{
		static::init();
		$data = [
			'email' => $email,
			'pass_sha1' => self::getEncryptedPass($pass),
			'sex' => $sex,
			'confirm_code' => $confirmCode
		];
		
		if (static::$_tableGW->insert($data))
			return self::getLastInsertedId();
		else
			return 0;
	}
	
	/**
	 * @return integer
	 */
	static function autoSignup($email, $pass, $sex, $inviteSenderId)
	{
		static::init();
		$data = [
			'email' => $email,
			'pass_sha1' => self::getEncryptedPass($pass),
			'confirm_code' => '',
			'sex' => $sex,
			'paired_user_id' => $inviteSenderId
		];

		if (static::$_tableGW->insert($data))
			return self::getLastInsertedId();
		else
			return 0;		
	}
	
	/**
	 * @return boolean
	 */
	static function accountExists($login)
	{
        static::init();
		$result = self::getByLogin($login);
		return (boolean)$result;
	}

	/**
	 * @return User|null
	 */
	static function getByLogin($login)
	{
        static::init();

		$result = static::$_tableGW->select(function (Select $select) use($login) {
			$select->where(['email' => $login, 'username' => $login], PredicateSet::OP_OR);
		});		
		
		if (!$result->count())
			return null;
		
		return new static($result->current());
	}
	
	/**
	 * @return string
	 */
	static function generateAccessToken()
	{
		return Core\get_unique_id(self::ACCESS_TOKEN_LENGTH);
	}
	
	/**
	 * @return string
	 */
	static function generateDefaultPass()
	{
		return Core\get_unique_id(self::DEFAULT_PASS_LENGTH);
	}

	/**
	 * @return void
	 */
	function setLocUpdateTime(\DateTime $time)
	{
		$this->locUpdateTime = $time;
		$this->dbTabRow->loc_update_time = $time->format('Y-m-d H:i:s');
	}
	
	/**
	 * @return \DateTime
	 */
	function getLocUpdateTime()
	{
		if (isset($this->locUpdateTime))
			return $this->locUpdateTime;
		
		$dt = new \DateTime($this->dbTabRow->loc_update_time);
		$this->locUpdateTime = $dt;
		return $dt;
	}
	
	/**
	 * Returns true if user account has been suspended
	 * 
	 * @return boolean
	 */
	function isSuspended()
	{
		return false;
	}
	
	/**
	 * @return boolean
	 */
	function isActive()
	{
		$confirmCode = $this->getConfirmCode();
		return !$this->isSuspended() && empty($confirmCode);
	}
	
	/**
	 * @return boolean
	 */
	function checkPass($pass)
	{
		return (boolean)$this->dbTabRow->pass_sha1 == sha1($pass . self::USER_SALT);
	}
	
	/**
	 * @return boolean
	 */
	function isFemale()
	{
		return $this->getSex() == self::SEX_FEMALE;
	}
	
	/**
	 * @return boolean
	 */
	function isMale()
	{
		return $this->getSex() == self::SEX_MALE;
	}
}
